<?php


declare(strict_types=1);

namespace App\Request;


use App\Constants\ErrorCode;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use HyperfException\Json;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

abstract class CommonRequest
{
    /**
     * 验证器名称
     * @var string
     */
    protected $name = '';

    /**
     * 验证规则
     * @var array
     */
    protected $rule = [];

    /**
     * 消息主体
     * @var array
     */
    protected $message = [];

    /**
     * 构造
     */
    public function __construct()
    {
        if (empty($this->rule))
            throw new json(ErrorCode::getMessage(ErrorCode::REQUEST_RULE_NULL), ErrorCode::REQUEST_RULE_NULL);
        if (!is_array($this->rule))
            throw new json(ErrorCode::getMessage(ErrorCode::REQUEST_RULE_NOT_ARRAY), ErrorCode::REQUEST_RULE_NOT_ARRAY);
        if (empty($this->message))
            throw new json(ErrorCode::getMessage(ErrorCode::REQUEST_MESSAGE_NULL), ErrorCode::REQUEST_MESSAGE_NULL);
        if (!is_array($this->message))
            throw new json(ErrorCode::getMessage(ErrorCode::REQUEST_MESSAGE_NOT_ARRAY), ErrorCode::REQUEST_MESSAGE_NOT_ARRAY);

    }

    /**
     * 验证规则
     * @param array $params
     * @param string $scenes
     * @return bool
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    protected function __validated(array $params, string $scenes): bool
    {
        if (empty($params))
            throw new json(ErrorCode::getMessage(ErrorCode::REQUEST_PARAMS_NULL), ErrorCode::REQUEST_PARAMS_NULL);
        if (!is_array($params))
            throw new json(ErrorCode::getMessage(ErrorCode::REQUEST_PARAMS_NOT_ARRAY), ErrorCode::REQUEST_PARAMS_NOT_ARRAY);
        if (empty($this->rule[(string)$scenes]))
            throw new json(ErrorCode::getMessage(ErrorCode::REQUEST_SCENES_NULL), ErrorCode::REQUEST_SCENES_NULL);
        $validator = ApplicationContext::getContainer()->get(ValidatorFactoryInterface::class)->make($params, $this->rule[(string)$scenes], $this->message);
        if ($validator->fails())
            throw new Json($validator->errors()->first(), ErrorCode::VALIDATE_PARAMS);
        return true;
    }
}